/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package entidade.controller.JPA;

import entidade.controller.JPA.exceptions.IllegalOrphanException;
import entidade.controller.JPA.exceptions.NonexistentEntityException;
import entidade.controller.JPA.exceptions.RollbackFailureException;
import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import entidade.persistencia.CategoriaProduto;
import entidade.persistencia.Produto;
import java.util.ArrayList;
import java.util.List;
import javax.transaction.UserTransaction;

/**
 *
 * @author victorinox
 */
public class CategoriaProdutoJpaController {
    @Resource
    private UserTransaction utx = null;
    @PersistenceUnit(unitName = "globalimage2PU")
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(CategoriaProduto categoriaProduto) throws RollbackFailureException, Exception {
        if (categoriaProduto.getProdutoCollection() == null) {
            categoriaProduto.setProdutoCollection(new ArrayList<Produto>());
        }
        if (categoriaProduto.getCategoriaProdutoCollection() == null) {
            categoriaProduto.setCategoriaProdutoCollection(new ArrayList<CategoriaProduto>());
        }
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            CategoriaProduto categoriaPaiId = categoriaProduto.getCategoriaPaiId();
            if (categoriaPaiId != null) {
                categoriaPaiId = em.getReference(categoriaPaiId.getClass(), categoriaPaiId.getCategoriaId());
                categoriaProduto.setCategoriaPaiId(categoriaPaiId);
            }
            List<Produto> attachedProdutoCollection = new ArrayList<Produto>();
            for (Produto produtoCollectionProdutoToAttach : categoriaProduto.getProdutoCollection()) {
                produtoCollectionProdutoToAttach = em.getReference(produtoCollectionProdutoToAttach.getClass(), produtoCollectionProdutoToAttach.getProdutoId());
                attachedProdutoCollection.add(produtoCollectionProdutoToAttach);
            }
            categoriaProduto.setProdutoCollection(attachedProdutoCollection);
            List<CategoriaProduto> attachedCategoriaProdutoCollection = new ArrayList<CategoriaProduto>();
            for (CategoriaProduto categoriaProdutoCollectionCategoriaProdutoToAttach : categoriaProduto.getCategoriaProdutoCollection()) {
                categoriaProdutoCollectionCategoriaProdutoToAttach = em.getReference(categoriaProdutoCollectionCategoriaProdutoToAttach.getClass(), categoriaProdutoCollectionCategoriaProdutoToAttach.getCategoriaId());
                attachedCategoriaProdutoCollection.add(categoriaProdutoCollectionCategoriaProdutoToAttach);
            }
            categoriaProduto.setCategoriaProdutoCollection(attachedCategoriaProdutoCollection);
            em.persist(categoriaProduto);
            if (categoriaPaiId != null) {
                categoriaPaiId.getCategoriaProdutoCollection().add(categoriaProduto);
                categoriaPaiId = em.merge(categoriaPaiId);
            }
            for (Produto produtoCollectionProduto : categoriaProduto.getProdutoCollection()) {
                CategoriaProduto oldCategoriaIdOfProdutoCollectionProduto = produtoCollectionProduto.getCategoriaId();
                produtoCollectionProduto.setCategoriaId(categoriaProduto);
                produtoCollectionProduto = em.merge(produtoCollectionProduto);
                if (oldCategoriaIdOfProdutoCollectionProduto != null) {
                    oldCategoriaIdOfProdutoCollectionProduto.getProdutoCollection().remove(produtoCollectionProduto);
                    oldCategoriaIdOfProdutoCollectionProduto = em.merge(oldCategoriaIdOfProdutoCollectionProduto);
                }
            }
            for (CategoriaProduto categoriaProdutoCollectionCategoriaProduto : categoriaProduto.getCategoriaProdutoCollection()) {
                CategoriaProduto oldCategoriaPaiIdOfCategoriaProdutoCollectionCategoriaProduto = categoriaProdutoCollectionCategoriaProduto.getCategoriaPaiId();
                categoriaProdutoCollectionCategoriaProduto.setCategoriaPaiId(categoriaProduto);
                categoriaProdutoCollectionCategoriaProduto = em.merge(categoriaProdutoCollectionCategoriaProduto);
                if (oldCategoriaPaiIdOfCategoriaProdutoCollectionCategoriaProduto != null) {
                    oldCategoriaPaiIdOfCategoriaProdutoCollectionCategoriaProduto.getCategoriaProdutoCollection().remove(categoriaProdutoCollectionCategoriaProduto);
                    oldCategoriaPaiIdOfCategoriaProdutoCollectionCategoriaProduto = em.merge(oldCategoriaPaiIdOfCategoriaProdutoCollectionCategoriaProduto);
                }
            }
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(CategoriaProduto categoriaProduto) throws IllegalOrphanException, NonexistentEntityException, RollbackFailureException, Exception {
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            CategoriaProduto persistentCategoriaProduto = em.find(CategoriaProduto.class, categoriaProduto.getCategoriaId());
            CategoriaProduto categoriaPaiIdOld = persistentCategoriaProduto.getCategoriaPaiId();
            CategoriaProduto categoriaPaiIdNew = categoriaProduto.getCategoriaPaiId();
            List<Produto> produtoCollectionOld = persistentCategoriaProduto.getProdutoCollection();
            List<Produto> produtoCollectionNew = categoriaProduto.getProdutoCollection();
            List<CategoriaProduto> categoriaProdutoCollectionOld = persistentCategoriaProduto.getCategoriaProdutoCollection();
            List<CategoriaProduto> categoriaProdutoCollectionNew = categoriaProduto.getCategoriaProdutoCollection();
            List<String> illegalOrphanMessages = null;
            for (Produto produtoCollectionOldProduto : produtoCollectionOld) {
                if (!produtoCollectionNew.contains(produtoCollectionOldProduto)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Produto " + produtoCollectionOldProduto + " since its categoriaId field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (categoriaPaiIdNew != null) {
                categoriaPaiIdNew = em.getReference(categoriaPaiIdNew.getClass(), categoriaPaiIdNew.getCategoriaId());
                categoriaProduto.setCategoriaPaiId(categoriaPaiIdNew);
            }
            List<Produto> attachedProdutoCollectionNew = new ArrayList<Produto>();
            for (Produto produtoCollectionNewProdutoToAttach : produtoCollectionNew) {
                produtoCollectionNewProdutoToAttach = em.getReference(produtoCollectionNewProdutoToAttach.getClass(), produtoCollectionNewProdutoToAttach.getProdutoId());
                attachedProdutoCollectionNew.add(produtoCollectionNewProdutoToAttach);
            }
            produtoCollectionNew = attachedProdutoCollectionNew;
            categoriaProduto.setProdutoCollection(produtoCollectionNew);
            List<CategoriaProduto> attachedCategoriaProdutoCollectionNew = new ArrayList<CategoriaProduto>();
            for (CategoriaProduto categoriaProdutoCollectionNewCategoriaProdutoToAttach : categoriaProdutoCollectionNew) {
                categoriaProdutoCollectionNewCategoriaProdutoToAttach = em.getReference(categoriaProdutoCollectionNewCategoriaProdutoToAttach.getClass(), categoriaProdutoCollectionNewCategoriaProdutoToAttach.getCategoriaId());
                attachedCategoriaProdutoCollectionNew.add(categoriaProdutoCollectionNewCategoriaProdutoToAttach);
            }
            categoriaProdutoCollectionNew = attachedCategoriaProdutoCollectionNew;
            categoriaProduto.setCategoriaProdutoCollection(categoriaProdutoCollectionNew);
            categoriaProduto = em.merge(categoriaProduto);
            if (categoriaPaiIdOld != null && !categoriaPaiIdOld.equals(categoriaPaiIdNew)) {
                categoriaPaiIdOld.getCategoriaProdutoCollection().remove(categoriaProduto);
                categoriaPaiIdOld = em.merge(categoriaPaiIdOld);
            }
            if (categoriaPaiIdNew != null && !categoriaPaiIdNew.equals(categoriaPaiIdOld)) {
                categoriaPaiIdNew.getCategoriaProdutoCollection().add(categoriaProduto);
                categoriaPaiIdNew = em.merge(categoriaPaiIdNew);
            }
            for (Produto produtoCollectionNewProduto : produtoCollectionNew) {
                if (!produtoCollectionOld.contains(produtoCollectionNewProduto)) {
                    CategoriaProduto oldCategoriaIdOfProdutoCollectionNewProduto = produtoCollectionNewProduto.getCategoriaId();
                    produtoCollectionNewProduto.setCategoriaId(categoriaProduto);
                    produtoCollectionNewProduto = em.merge(produtoCollectionNewProduto);
                    if (oldCategoriaIdOfProdutoCollectionNewProduto != null && !oldCategoriaIdOfProdutoCollectionNewProduto.equals(categoriaProduto)) {
                        oldCategoriaIdOfProdutoCollectionNewProduto.getProdutoCollection().remove(produtoCollectionNewProduto);
                        oldCategoriaIdOfProdutoCollectionNewProduto = em.merge(oldCategoriaIdOfProdutoCollectionNewProduto);
                    }
                }
            }
            for (CategoriaProduto categoriaProdutoCollectionOldCategoriaProduto : categoriaProdutoCollectionOld) {
                if (!categoriaProdutoCollectionNew.contains(categoriaProdutoCollectionOldCategoriaProduto)) {
                    categoriaProdutoCollectionOldCategoriaProduto.setCategoriaPaiId(null);
                    categoriaProdutoCollectionOldCategoriaProduto = em.merge(categoriaProdutoCollectionOldCategoriaProduto);
                }
            }
            for (CategoriaProduto categoriaProdutoCollectionNewCategoriaProduto : categoriaProdutoCollectionNew) {
                if (!categoriaProdutoCollectionOld.contains(categoriaProdutoCollectionNewCategoriaProduto)) {
                    CategoriaProduto oldCategoriaPaiIdOfCategoriaProdutoCollectionNewCategoriaProduto = categoriaProdutoCollectionNewCategoriaProduto.getCategoriaPaiId();
                    categoriaProdutoCollectionNewCategoriaProduto.setCategoriaPaiId(categoriaProduto);
                    categoriaProdutoCollectionNewCategoriaProduto = em.merge(categoriaProdutoCollectionNewCategoriaProduto);
                    if (oldCategoriaPaiIdOfCategoriaProdutoCollectionNewCategoriaProduto != null && !oldCategoriaPaiIdOfCategoriaProdutoCollectionNewCategoriaProduto.equals(categoriaProduto)) {
                        oldCategoriaPaiIdOfCategoriaProdutoCollectionNewCategoriaProduto.getCategoriaProdutoCollection().remove(categoriaProdutoCollectionNewCategoriaProduto);
                        oldCategoriaPaiIdOfCategoriaProdutoCollectionNewCategoriaProduto = em.merge(oldCategoriaPaiIdOfCategoriaProdutoCollectionNewCategoriaProduto);
                    }
                }
            }
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = categoriaProduto.getCategoriaId();
                if (findCategoriaProduto(id) == null) {
                    throw new NonexistentEntityException("The categoriaProduto with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException, RollbackFailureException, Exception {
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            CategoriaProduto categoriaProduto;
            try {
                categoriaProduto = em.getReference(CategoriaProduto.class, id);
                categoriaProduto.getCategoriaId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The categoriaProduto with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<Produto> produtoCollectionOrphanCheck = categoriaProduto.getProdutoCollection();
            for (Produto produtoCollectionOrphanCheckProduto : produtoCollectionOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This CategoriaProduto (" + categoriaProduto + ") cannot be destroyed since the Produto " + produtoCollectionOrphanCheckProduto + " in its produtoCollection field has a non-nullable categoriaId field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            CategoriaProduto categoriaPaiId = categoriaProduto.getCategoriaPaiId();
            if (categoriaPaiId != null) {
                categoriaPaiId.getCategoriaProdutoCollection().remove(categoriaProduto);
                categoriaPaiId = em.merge(categoriaPaiId);
            }
            List<CategoriaProduto> categoriaProdutoCollection = categoriaProduto.getCategoriaProdutoCollection();
            for (CategoriaProduto categoriaProdutoCollectionCategoriaProduto : categoriaProdutoCollection) {
                categoriaProdutoCollectionCategoriaProduto.setCategoriaPaiId(null);
                categoriaProdutoCollectionCategoriaProduto = em.merge(categoriaProdutoCollectionCategoriaProduto);
            }
            em.remove(categoriaProduto);
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<CategoriaProduto> findCategoriaProdutoEntities() {
        return findCategoriaProdutoEntities(true, -1, -1);
    }

    public List<CategoriaProduto> findCategoriaProdutoEntities(int maxResults, int firstResult) {
        return findCategoriaProdutoEntities(false, maxResults, firstResult);
    }

    private List<CategoriaProduto> findCategoriaProdutoEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select object(o) from CategoriaProduto as o");
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public CategoriaProduto findCategoriaProduto(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(CategoriaProduto.class, id);
        } finally {
            em.close();
        }
    }

    public int getCategoriaProdutoCount() {
        EntityManager em = getEntityManager();
        try {
            return ((Long) em.createQuery("select count(o) from CategoriaProduto as o").getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

}
